<?php

require_once 'PHPUnit/Framework.php';
require_once '../occam.class.php';

class OccamCases extends PHPUnit_Framework_TestCase {

	public function testTTLBasic() {
		// cache for 5 seconds
		$cache = new occam(NULL, 5);

		// get initial expected value
		$expected = $cache->execute(__FUNCTION__, 'time');

		// if already cached (from previous test), ensure uncached live data
		if($cache->is_cached()) {
			$cache->set_ttl(1);
			sleep(1);
			$expected = $cache->execute(__FUNCTION__, 'time');
			$cache->set_ttl(5);
		}

		// after 3 seconds, should still be equal
		sleep(3);
		$test = $cache->execute(__FUNCTION__, 'time');
		$this->assertEquals($test, $expected);

		// after 3 more seconds, should be not equal
		sleep(3);
		$test = $cache->execute(__FUNCTION__, 'time');
		$this->assertNotEquals($test, $expected);
	}

	public function testIsCached() {
		$cache = new occam(NULL, 5);

		// make request(s) that should be cached
		$cache->execute(__FUNCTION__, 'time');
		$cache->execute(__FUNCTION__, 'time');
		$this->assertTrue($cache->is_cached());

		$cache->set_ttl(0);

		// make request that should NOT be cached
		$data = $cache->execute(__FUNCTION__, 'time');
		$this->assertFalse($cache->is_cached());
	}

	public function testExtendTTL() {
		$cache = new occam(NULL, 1);

		// ensure content initially cached
		$cache->execute(__FUNCTION__, 'time');
		$cache->execute(__FUNCTION__, 'time');
		$this->assertTrue($cache->is_cached());

		// sleep past expiry date
		sleep(2);

		// extend ttl and expect still cached data
		$cache->set_ttl(300);
		$cache->execute(__FUNCTION__, 'time');
		$this->assertTrue($cache->is_cached());

		// directly open cache file
		$cache_filename = $cache->get_directory() . '/' . md5(__FUNCTION__) . '.' . occam::CACHE_FILE_EXT;
		$handle = @fopen($cache_filename, 'r');
		$this->assertNotSame($handle, FALSE);

		// retrieve embedded ttl and verify still original value (1)
		$ttl = @fread($handle, 4);
		@fclose($handle);
		$this->assertEquals( $ttl , @pack('N', 1) );
	}

	public function testShortenTTL() {
		$cache = new occam(NULL, 300);

		// ensure content initially cached
		$cache->execute(__FUNCTION__, 'time');
		$cache->execute(__FUNCTION__, 'time');
		$this->assertTrue($cache->is_cached());

		// sleep past expiry date
		sleep(2);

		// extend ttl and expect still cached data
		$cache->set_ttl(1);
		$cache->execute(__FUNCTION__, 'time');
		$this->assertFalse($cache->is_cached());

		// directly open cache file
		$cache_filename = $cache->get_directory() . '/' . md5(__FUNCTION__) . '.' . occam::CACHE_FILE_EXT;
		$handle = @fopen($cache_filename, 'r');
		$this->assertNotSame($handle, FALSE);

		// retrieve embedded ttl and verify still original value (1)
		$ttl = @fread($handle, 4);
		@fclose($handle);
		$this->assertEquals( $ttl , @pack('N', 1) );
	}

	public function testTidyFromAccessor() {
		$cache = new occam(NULL, 1);

		// ensure content initially cached
		$cache->execute(__FUNCTION__, 'time');

		// cache data, and verify cache file exists
		$cache_filename = $cache->get_directory() . '/' . md5(__FUNCTION__) . '.' . occam::CACHE_FILE_EXT;
		$this->assertTrue( file_exists($cache_filename) );

		// sleep past expiry date, and turn on tidy mode
		sleep(2);
		$cache->set_tidy(TRUE);

		// cache unrelated data to trigger tidying, then check existence of previous cache file
		$cache->execute(time(), 'time');
		$this->assertFalse( file_exists($cache_filename) );
	}

	public function testTidyFromConstructor() {
		// ensure content initially cached
		$cache = new occam(NULL, 1);
		$cache->execute(__FUNCTION__, 'time');

		// create new instance with tidy mode turned on in constructor
		$cache = new occam(NULL, 1, TRUE);

		// cache data, and verify cache file exists
		$cache_filename = $cache->get_directory() . '/' . md5(__FUNCTION__) . '.' . occam::CACHE_FILE_EXT;
		$this->assertTrue( file_exists($cache_filename) );

		// sleep past expiry date
		sleep(2);

		// cache unrelated data to trigger tidying, then check existence of previous cache file
		$cache->execute(time(), 'time');
		$this->assertFalse( file_exists($cache_filename) );
	}
}

/***/
// this allows us to run tests through apache
if(isset($_SERVER['HTTP_HOST']) ) {
	define('COMMAND_SEPARATOR', strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? '&' : ';');
	@header('Content-Type: text/plain; charset=utf-8');
	echo shell_exec(
		sprintf(
			'cd %s ' . COMMAND_SEPARATOR . ' phpunit %s %s',
			dirname(__FILE__),
			escapeshellcmd(@$_REQUEST['args']),
			substr(basename(__FILE__), 0, strlen(basename(__FILE__))-4 )
		)
	);
}
/***/
